package edu.ptu.acl.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import edu.ptu.acl.common.AdminValidate;
import edu.ptu.acl.common.RequestHolder;
import edu.ptu.acl.dto.AclTreeDto;
import edu.ptu.acl.dto.DeptTreeDto;
import edu.ptu.acl.entity.*;
import edu.ptu.acl.exception.ApiException;
import edu.ptu.acl.mapper.AclMapper;
import edu.ptu.acl.mapper.RoleAclMapper;
import edu.ptu.acl.mapper.RoleMapper;
import edu.ptu.acl.mapper.RoleUserMapper;
import edu.ptu.acl.service.IAclService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import edu.ptu.acl.service.IRoleAclService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author LinJC
 * @since 2022-03-15
 */
@Service
public class AclServiceImpl extends ServiceImpl<AclMapper, Acl> implements IAclService {

    @Resource
    private AclMapper aclMapper;
    @Resource
    private RoleUserMapper roleUserMapper;
    @Resource
    private RoleAclMapper roleAclMapper;
    @Resource
    private RoleMapper roleMapper;

    @Override
    public List<AclTreeDto> getAclTreeDto() {
        List<Acl> aclList = aclMapper.selectList(null);
        Multimap<Long, AclTreeDto> aclTreeDtoMultimap = ArrayListMultimap.create();

        for (Acl acl : aclList) {
            AclTreeDto aclTreeDto = AclTreeDto.copyDept(acl);
            aclTreeDtoMultimap.put(aclTreeDto.getParentId(),aclTreeDto);
        }

        List<AclTreeDto> rootAclTreeDtoList = (List<AclTreeDto>)aclTreeDtoMultimap.get(0L);
        Collections.sort(rootAclTreeDtoList,(d1, d2) -> d1.getSeq()-d2.getSeq());

        recursionAclTree(rootAclTreeDtoList,aclTreeDtoMultimap);

        return rootAclTreeDtoList;
    }

    public void recursionAclTree(List<AclTreeDto> rootAclTreeDtoList, Multimap<Long, AclTreeDto> aclTreeDtoMultimap) {
        if (CollectionUtils.isEmpty(rootAclTreeDtoList)){
            return;
        }
        for (AclTreeDto aclTreeDto : rootAclTreeDtoList) {
            List<AclTreeDto> sonAclTreeDtoList = (List<AclTreeDto>)aclTreeDtoMultimap.get(aclTreeDto.getId());

            if (CollectionUtils.isNotEmpty(sonAclTreeDtoList)){
                aclTreeDto.setHasChildren(false);
            }

            Collections.sort(sonAclTreeDtoList,(d1,d2) -> d1.getSeq()-d2.getSeq() );

            aclTreeDto.setSonAclTreeDtoList(sonAclTreeDtoList);
            recursionAclTree(sonAclTreeDtoList,aclTreeDtoMultimap);
        }
    }

    /*
     * 生成路由权限
     * 1.得到当前用户
     * 2.得到用户拥有的角色
     * 3.得到角色拥有的路由权限
     * 4.生成权限idList
     * */
    @Override
    public List<Acl> getCurrentUserAclList() {

        if (AdminValidate.isAdmin()){
            return aclMapper.selectList(null);
        }

        User currentUser = RequestHolder.getCurrentUser();
        Long userId = currentUser.getId();
        QueryWrapper<RoleUser> roleUserQueryWrapper = new QueryWrapper<>();
        roleUserQueryWrapper.eq("user_id",userId);
        List<RoleUser> allRoleUsers = roleUserMapper.selectList(roleUserQueryWrapper);
        List<RoleUser> roleUsers = new ArrayList<>();

        Set<Long> aclIds = new HashSet<>();
        QueryWrapper<RoleAcl> roleAclQueryWrapper = new QueryWrapper<>();

        if (CollectionUtils.isEmpty(allRoleUsers)){
            return null;
        }
        // 排除冻结的角色

        for (RoleUser roleUser : allRoleUsers) {
            QueryWrapper<Role> roleQueryWrapper = new QueryWrapper<>();
            roleQueryWrapper.eq("status","0");
            roleQueryWrapper.eq("id",roleUser.getRoleId());
            if (roleMapper.selectCount(roleQueryWrapper)==0) {
                roleUsers.add(roleUser);
            }
        }


        for (RoleUser roleUser : roleUsers) {
            roleAclQueryWrapper.clear();
            roleAclQueryWrapper.eq("role_id",roleUser.getRoleId());
            List<RoleAcl> roleAclList = roleAclMapper.selectList(roleAclQueryWrapper);
            if (CollectionUtils.isNotEmpty(roleAclList)){
                for (RoleAcl roleAcl : roleAclList) {
                    aclIds.add(roleAcl.getAclId());
                }
            }

        }

        if (CollectionUtils.isEmpty(aclIds)){
            return null;
        }

        List<Acl> aclList = aclMapper.selectBatchIds(aclIds);

        return aclList;
    }

    @Override
    public void deleteAcl(List<Long> ids) {
        // 有子级acl不允许删除
        QueryWrapper<Acl> aclQueryWrapper = new QueryWrapper<>();
        for (Long id : ids) {
            aclQueryWrapper.clear();
            aclQueryWrapper.eq("parent_id",id);
            if (aclMapper.selectCount(aclQueryWrapper)!=0) {
                throw new ApiException("请先删除子级权限");
            }
        }

        // 删除roleacl关系
        QueryWrapper<RoleAcl> roleAclQueryWrapper = new QueryWrapper<>();
        for (Long id : ids) {
            roleAclQueryWrapper.clear();
            roleAclQueryWrapper.eq("acl_id",id);
            roleAclMapper.delete(roleAclQueryWrapper);
        }

        aclMapper.deleteBatchIds(ids);
    }
}
